using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Http;

namespace CKY.AgentPlatform.ModelConfigs
{
    /// <summary>
    /// 增强的模型适配器基类
    /// </summary>
    public abstract class EnhancedModelAdapterBase : IModelInvocationAdapter
    {
        private readonly ILogger<EnhancedModelAdapterBase> _logger;
        private readonly ModelCircuitBreaker _circuitBreaker;
        private readonly ModelMonitoringService _monitoringService;
        private readonly IHttpClientFactory _httpClientFactory;

        protected EnhancedModelAdapterBase(
            ILogger<EnhancedModelAdapterBase> logger,
            ModelCircuitBreaker circuitBreaker,
            ModelMonitoringService monitoringService,
            IHttpClientFactory httpClientFactory)
        {
            _logger = logger ?? throw new ArgumentNullException(nameof(logger));
            _circuitBreaker = circuitBreaker ?? throw new ArgumentNullException(nameof(circuitBreaker));
            _monitoringService = monitoringService ?? throw new ArgumentNullException(nameof(monitoringService));
            _httpClientFactory = httpClientFactory ?? throw new ArgumentNullException(nameof(httpClientFactory));

            // 订阅熔断器状态变更事件
            _circuitBreaker.StateChanged += OnCircuitBreakerStateChanged;
        }

        /// <summary>
        /// 抽象属性：支持的API模式
        /// </summary>
        public abstract ModelApiMode SupportedMode { get; }

        /// <summary>
        /// 抽象属性：支持的模型提供商
        /// </summary>
        public abstract ModelProvider SupportedProvider { get; }

        /// <summary>
        /// 抽象属性：适配器名称
        /// </summary>
        public abstract string Name { get; }

        /// <summary>
        /// 抽象属性：适配器版本
        /// </summary>
        public abstract string Version { get; }

        /// <summary>
        /// 抽象属性：是否支持流式输出
        /// </summary>
        public abstract bool SupportsStreaming { get; }

        /// <summary>
        /// 抽象属性：是否支持工具调用
        /// </summary>
        public abstract bool SupportsToolCalling { get; }

        /// <summary>
        /// 执行模型调用（增强版）
        /// </summary>
        public async Task<ModelInvocationResponse> InvokeAsync(
            ModelInvocationConfig config,
            ModelInvocationRequest request,
            string executionId)
        {
            var executionRecord = new ModelExecutionRecord
            {
                ExecutionId = executionId,
                Provider = SupportedProvider,
                ModelName = request.Model,
                ApiMode = SupportedMode,
                AdapterName = Name,
                UserId = request.UserId,
                SessionId = request.SessionId,
                StartTime = DateTime.UtcNow,
                InputMessageCount = request.Messages?.Count ?? 0,
                InputCharacters = request.Messages?.Sum(m => m.Content?.Length ?? 0) ?? 0,
                Metadata = request.Metadata ?? new Dictionary<string, object>()
            };

            try
            {
                // 使用熔断器保护
                var response = await _circuitBreaker.ExecuteAsync(async () =>
                {
                    return await ExecuteWithRetryAsync(config, request, executionId, executionRecord);
                });

                // 记录成功执行
                executionRecord.Success = response.Success;
                executionRecord.TokensUsed = response.Usage?.TotalTokens ?? 0;
                executionRecord.OutputCharacters = response.Response?.Content?.Length ?? 0;

                return response;
            }
            catch (CircuitBreakerOpenException ex)
            {
                // 熔断器开启，记录特殊的错误
                _logger.LogWarning(ex, "熔断器开启，拒绝请求: {AdapterName}, 执行ID: {ExecutionId}", Name, executionId);

                executionRecord.Success = false;
                executionRecord.ErrorType = ModelErrorType.ModelUnavailableError;
                executionRecord.ErrorMessage = ex.Message;

                return new ModelInvocationResponse
                {
                    Error = new ErrorResponse
                    {
                        Code = "CIRCUIT_BREAKER_OPEN",
                        Message = ex.Message,
                        Type = "CircuitBreakerError"
                    },
                    UsedApiMode = SupportedMode
                };
            }
            catch (Exception ex)
            {
                // 分类错误
                var errorInfo = ModelErrorClassifier.ClassifyException(ex, new Dictionary<string, object>
                {
                    ["AdapterName"] = Name,
                    ["ExecutionId"] = executionId,
                    ["ModelName"] = request.Model
                });

                executionRecord.Success = false;
                executionRecord.ErrorType = errorInfo.ErrorType;
                executionRecord.ErrorMessage = errorInfo.ErrorMessage;

                _logger.LogError(ex, "模型调用失败: {AdapterName}, 执行ID: {ExecutionId}, 错误类型: {ErrorType}",
                    Name, executionId, errorInfo.ErrorType);

                return new ModelInvocationResponse
                {
                    Error = new ErrorResponse
                    {
                        Code = errorInfo.ErrorCode,
                        Message = errorInfo.ErrorMessage,
                        Type = errorInfo.ErrorType.ToString(),
                        InnerException = ex
                    },
                    UsedApiMode = SupportedMode
                };
            }
            finally
            {
                // 记录执行信息
                _monitoringService.RecordExecution(executionRecord);
            }
        }

        /// <summary>
        /// 带重试的执行
        /// </summary>
        private async Task<ModelInvocationResponse> ExecuteWithRetryAsync(
            ModelInvocationConfig config,
            ModelInvocationRequest request,
            string executionId,
            ModelExecutionRecord executionRecord)
        {
            var maxRetries = config.MaxRetries;
            var lastException = new Exception();

            for (int attempt = 1; attempt <= maxRetries; attempt++)
            {
                try
                {
                    var response = await ExecuteInternalAsync(config, request, executionId);

                    // HTTP错误分类
                    if (!response.Success && response.Error != null)
                    {
                        var statusCode = GetHttpStatusCode(response.Error);
                        if (statusCode.HasValue)
                        {
                            var httpError = ModelErrorClassifier.ClassifyHttpError(statusCode.Value);

                            // 检查是否需要重试
                            if (attempt < maxRetries && httpError.CanRetry)
                            {
                                _logger.LogWarning("HTTP错误，准备重试: {Attempt}/{MaxRetries}, 状态码: {StatusCode}, 错误: {ErrorMessage}",
                                    attempt, maxRetries, statusCode, httpError.ErrorMessage);

                                executionRecord.RetryCount++;

                                // 应用延迟策略
                                var delayMs = CalculateDelayMs(httpError.SuggestedDelayMs, attempt);
                                await Task.Delay(delayMs);

                                lastException = new InvalidOperationException(httpError.ErrorMessage);
                                continue;
                            }
                        }
                    }

                    return response;
                }
                catch (Exception ex) when (attempt < maxRetries)
                {
                    var errorInfo = ModelErrorClassifier.ClassifyException(ex);

                    if (errorInfo.CanRetry)
                    {
                        _logger.LogWarning(ex, "调用失败，准备重试: {Attempt}/{MaxRetries}, 执行ID: {ExecutionId}",
                            attempt, maxRetries, executionId);

                        executionRecord.RetryCount++;

                        // 应用延迟策略
                        var delayMs = CalculateDelayMs(errorInfo.SuggestedDelayMs, attempt);
                        await Task.Delay(delayMs);

                        lastException = ex;
                    }
                    else
                    {
                        // 不可重试的错误，直接抛出
                        throw;
                    }
                }
            }

            // 所有重试都失败了
            throw lastException;
        }

        /// <summary>
        /// 内部执行方法（子类实现）
        /// </summary>
        protected abstract Task<ModelInvocationResponse> ExecuteInternalAsync(
            ModelInvocationConfig config,
            ModelInvocationRequest request,
            string executionId);

        /// <summary>
        /// 验证配置是否有效
        /// </summary>
        public virtual bool ValidateConfig(ModelInvocationConfig config)
        {
            if (config == null)
                return false;

            // 基本配置验证
            if (string.IsNullOrWhiteSpace(config.GetEndpointForMode(SupportedMode)))
                return false;

            // API密钥验证
            if (!config.ModelSpecificParams.ContainsKey("ApiKey") &&
                !config.CustomHeaders.ContainsKey("Authorization"))
                return false;

            // 模型验证（从ModelSpecificParams中获取模型名称）
            if (!config.ModelSpecificParams.ContainsKey("Model") ||
                string.IsNullOrWhiteSpace(config.ModelSpecificParams["Model"]?.ToString()))
                return false;

            return true;
        }

        /// <summary>
        /// 获取适配器功能描述
        /// </summary>
        public abstract AdapterCapabilities GetCapabilities();

        /// <summary>
        /// 测试连接
        /// </summary>
        public virtual async Task<ConnectionTestResult> TestConnectionAsync(ModelInvocationConfig config)
        {
            try
            {
                var startTime = DateTime.UtcNow;

                // 使用熔断器保护连接测试
                await _circuitBreaker.ExecuteAsync(async () =>
                {
                    var testRequest = new ModelInvocationRequest
                    {
                        Model = config.SupportedModels?.FirstOrDefault() ?? "test",
                        Messages = new List<ChatMessage>
                        {
                            new ChatMessage { Role = "user", Content = "Hello" }
                        },
                        MaxTokens = 5,
                        Temperature = 0.1
                    };

                    await ExecuteInternalAsync(config, testRequest, Guid.NewGuid().ToString());
                });

                var responseTime = (long)(DateTime.UtcNow - startTime).TotalMilliseconds;

                return new ConnectionTestResult
                {
                    Success = true,
                    ResponseTimeMs = responseTime,
                    Details = new Dictionary<string, object>
                    {
                        ["adapter"] = Name,
                        ["provider"] = SupportedProvider.ToString(),
                        ["api_mode"] = SupportedMode.ToString()
                    }
                };
            }
            catch (CircuitBreakerOpenException ex)
            {
                return new ConnectionTestResult
                {
                    Success = false,
                    ErrorMessage = $"熔断器开启: {ex.Message}",
                    Details = new Dictionary<string, object>
                    {
                        ["adapter"] = Name,
                        ["circuit_state"] = "Open"
                    }
                };
            }
            catch (Exception ex)
            {
                return new ConnectionTestResult
                {
                    Success = false,
                    ErrorMessage = ex.Message,
                    Details = new Dictionary<string, object>
                    {
                        ["adapter"] = Name,
                        ["exception_type"] = ex.GetType().Name
                    }
                };
            }
        }

        /// <summary>
        /// 发送HTTP请求
        /// </summary>
        protected async Task<HttpResponseMessage> SendHttpRequestAsync(
            ModelInvocationConfig config,
            HttpMethod method,
            string url,
            HttpContent content,
            TimeSpan? timeout = null)
        {
            var httpClient = _httpClientFactory.CreateClient();

            // 设置请求头
            httpClient.DefaultRequestHeaders.Clear();
            foreach (var header in config.CustomHeaders)
            {
                httpClient.DefaultRequestHeaders.Add(header.Key, header.Value);
            }

            // 设置超时
            if (timeout.HasValue)
            {
                httpClient.Timeout = timeout.Value;
            }

            var request = new HttpRequestMessage(method, url)
            {
                Content = content
            };

            return await httpClient.SendAsync(request);
        }

        /// <summary>
        /// 构建JSON请求内容
        /// </summary>
        protected HttpContent BuildJsonContent(object data)
        {
            return new StringContent(
                JsonSerializer.Serialize(data),
                Encoding.UTF8,
                "application/json"
            );
        }

        /// <summary>
        /// 解析JSON响应
        /// </summary>
        protected JsonElement ParseJsonResponse(string responseContent)
        {
            try
            {
                using var jsonDoc = System.Text.Json.JsonDocument.Parse(responseContent);
                return jsonDoc.RootElement;
            }
            catch (System.Text.Json.JsonException ex)
            {
                var errorInfo = ModelErrorClassifier.ClassifyJsonException(ex, new ModelErrorInfo());
                throw new InvalidOperationException($"JSON解析失败: {errorInfo.ErrorMessage}", ex);
            }
        }

        /// <summary>
        /// 计算延迟时间
        /// </summary>
        /// <param name="baseDelayMs">基础延迟（毫秒）</param>
        /// <param name="attempt">尝试次数</param>
        /// <returns>延迟时间（毫秒）</returns>
        private int CalculateDelayMs(int baseDelayMs, int attempt)
        {
            // 指数退避策略
            return baseDelayMs * (int)Math.Pow(2, attempt - 1);
        }

        /// <summary>
        /// 从错误响应中获取HTTP状态码
        /// </summary>
        /// <param name="error">错误响应</param>
        /// <returns>HTTP状态码</returns>
        private System.Net.HttpStatusCode? GetHttpStatusCode(ErrorResponse error)
        {
            if (error?.Param?.TryGetValue("statusCode", out var statusCodeObj) == true)
            {
                if (System.Enum.TryParse<System.Net.HttpStatusCode>(statusCodeObj.ToString(), out var statusCode))
                {
                    return statusCode;
                }
            }

            // 尝试从错误代码中解析
            if (error?.Code?.StartsWith("HTTP_") == true)
            {
                var statusCodeStr = error.Code.Substring(5);
                if (System.Enum.TryParse<System.Net.HttpStatusCode>(statusCodeStr, out var statusCode))
                {
                    return statusCode;
                }
            }

            return null;
        }

        /// <summary>
        /// 熔断器状态变更处理
        /// </summary>
        /// <param name="sender">发送者</param>
        /// <param name="e">事件参数</param>
        private void OnCircuitBreakerStateChanged(object sender, CircuitBreakerEventArgs e)
        {
            var level = e.NewState switch
            {
                CircuitState.Open => LogLevel.Warning,
                CircuitState.HalfOpen => LogLevel.Information,
                CircuitState.Closed => LogLevel.Information,
                _ => LogLevel.Information
            };

            _logger.Log(level, "熔断器状态变更: {AdapterName}, {OldState} -> {NewState}, 原因: {Reason}",
                Name, e.OldState, e.NewState, e.Reason);

            // 记录状态变更指标
            _monitoringService.IncrementCounter("circuit_breaker_state_changes_total", new Dictionary<string, string>
            {
                ["adapter"] = Name,
                ["old_state"] = e.OldState.ToString(),
                ["new_state"] = e.NewState.ToString(),
                ["reason"] = e.Reason
            });
        }

        /// <summary>
        /// 获取熔断器统计信息
        /// </summary>
        /// <returns>统计信息</returns>
        public CircuitBreakerStats GetCircuitBreakerStats()
        {
            return _circuitBreaker.GetStats();
        }

        /// <summary>
        /// 重置熔断器
        /// </summary>
        public void ResetCircuitBreaker()
        {
            _circuitBreaker.Reset();
            _logger.LogInformation("重置熔断器: {AdapterName}", Name);
        }
    }
}